#include "glwidget.h"

void GLWidget::myMousePressEvent(QMouseEvent *event)
{
    lastPos = event->pos();
    lastClickPos = event->pos();
    //COMBINE
    if ((mode==CELL_SELECT && viewMode != CELL_FOURVIEW && selectMode==CELL_SELECT) || (mode==CELL_TRANSLATE && viewMode != CELL_FOURVIEW && selectMode == CELL_SELECT))
    {
        // reset so that nothing is selected because you are picking a new object
        if(glandular->isSurfaceConstructed())
        {
            glandular->resetSelectedPoint();
            glandular->resetSelectedFace();
        }
        for (size_t i=0;i<objects.size();i++)
        {
            objects[i]->resetSelectedPoint();
            objects[i]->resetSelectedFace();
        }

        pick(event->x(), event->y());
        isAreaSelected = false;
        if (selectObject == 0)
        {
            setTranslateX(glandular->getTranslateX());
            setTranslateY(glandular->getTranslateY());
            setTranslateZ(glandular->getTranslateZ());
            setRotateX(glandular->getRotateX());
            setRotateY(glandular->getRotateY());
            setRotateZ(glandular->getRotateZ());
            setScaleX(glandular->getScaleX());
            setScaleY(glandular->getScaleY());
            setScaleZ(glandular->getScaleZ());
        }
        else if (selectObject > 1)
        {
            setTranslateX((objects[selectObject-2])->getTranslateX());
            setTranslateY((objects[selectObject-2])->getTranslateY());
            setTranslateZ((objects[selectObject-2])->getTranslateZ());
            setRotateX((objects[selectObject-2])->getRotateX());
            setRotateY((objects[selectObject-2])->getRotateY());
            setRotateZ((objects[selectObject-2])->getRotateZ());
            setScaleX((objects[selectObject-2])->getScaleX());
            setScaleY((objects[selectObject-2])->getScaleY());
            setScaleZ((objects[selectObject-2])->getScaleZ());
        }
        setInputType();
        if(event->button() == Qt::RightButton && selectObject>1)
        {
            emit rightClickSelect(event->screenPos().toPoint());
        }
    }
    //COMBINE
    else if ((mode==CELL_SELECT && viewMode == CELL_FOURVIEW && selectMode==CELL_SELECT) || (mode == CELL_TRANSLATE && viewMode == CELL_FOURVIEW && selectMode == CELL_SELECT))
    {
        if(glandular->isSurfaceConstructed())
        {
            glandular->resetSelectedPoint();
            glandular->resetSelectedFace();
        }
        for (size_t i=0;i<objects.size();i++)
        {
            objects[i]->resetSelectedPoint();
            objects[i]->resetSelectedFace();
        }
        pickInFourView(event->x(), event->y());
        isAreaSelected = false;
        if (selectObject == 0)
        {
            setTranslateX(glandular->getTranslateX());
            setTranslateY(glandular->getTranslateY());
            setTranslateZ(glandular->getTranslateZ());
            setRotateX(glandular->getRotateX());
            setRotateY(glandular->getRotateY());
            setRotateZ(glandular->getRotateZ());
            setScaleX(glandular->getScaleX());
            setScaleY(glandular->getScaleY());
            setScaleZ(glandular->getScaleZ());
        }
        else if (selectObject > 1)
        {
            setTranslateX((objects[selectObject-2])->getTranslateX());
            setTranslateY((objects[selectObject-2])->getTranslateY());
            setTranslateZ((objects[selectObject-2])->getTranslateZ());
            setRotateX((objects[selectObject-2])->getRotateX());
            setRotateY((objects[selectObject-2])->getRotateY());
            setRotateZ((objects[selectObject-2])->getRotateZ());
            setScaleX((objects[selectObject-2])->getScaleX());
            setScaleY((objects[selectObject-2])->getScaleY());
            setScaleZ((objects[selectObject-2])->getScaleZ());
        }
    }
    if (mode == CELL_SELECT && selectMode == CELL_EDITMESHPOINT)
    {
        if (keyValue!=CELL_SHIFT)
        {
            if(glandular->isSurfaceConstructed())
            {
                glandular->resetSelectedPoint();
            }
            for (size_t i=0;i<objects.size();i++)
            {
                objects[i]->resetSelectedPoint();
            }
        }
        pickEditPoint(event->x(), event->y());
        isAreaSelected = false;
    }
    if (mode==CELL_SELECT&&selectMode==CELL_EDITMESHFACE)
    {
        if (keyValue!=CELL_SHIFT)
        {
            if(glandular->isSurfaceConstructed())
            {
                glandular->resetSelectedFace();
            }
            for (size_t i=0;i<objects.size();i++)
            {
                objects[i]->resetSelectedFace();
            }
        }
        pickEditFace(event->x(), event->y());
        isAreaSelected = false;
    }
    if (selectMode==CELL_EDITMESHPOINT && mode==CELL_TRANSLATE)
    {
        Vector3 center;
        if (selectObject==0)
        {
            if (glandular->selectPointsCenter(center)>0)
            {
                pickEditMeshTranslateAxis(event->x(), event->y(), center.x, center.y, center.z, glandular->getRotateX(),
                                          glandular->getRotateY(), glandular->getRotateZ());
            }
        } else if (selectObject>1)
        {
            if (objects[selectObject-2]->selectPointsCenter(center)>0)
            {
                pickEditMeshTranslateAxis(event->x(), event->y(), center.x, center.y, center.z, objects[selectObject-2]->getRotateX(),
                        objects[selectObject-2]->getRotateY(), objects[selectObject-2]->getRotateZ());
            }
        }
    }
    if (selectMode==CELL_EDITMESHFACE&&mode==CELL_TRANSLATE)
    {
        Vector3 center;
        if (selectObject==0)
        {
            if(glandular->isSurfaceConstructed() && glandular->selectFacesCenter(center) > 0)
            {
                pickEditMeshTranslateAxis(event->x(), event->y(), center.x, center.y, center.z, glandular->getRotateX(),
                                          glandular->getRotateY(), glandular->getRotateZ());
            }
        }
        else if (selectObject > 1)
        {
            if (objects[selectObject-2]->selectFacesCenter(center) > 0)
            {
                pickEditMeshTranslateAxis(event->x(), event->y(), center.x, center.y, center.z, objects[selectObject-2]->getRotateX(),
                        objects[selectObject-2]->getRotateY(), objects[selectObject-2]->getRotateZ());
            }
        }
    }
    if (selectMode == CELL_SELECT && mode == CELL_TRANSLATE)
    {
//        int lastSelect = selectObject;
//        if (viewMode==CELL_FOURVIEW) {
//            pickInFourView(event->x(), event->y());
//        } else {
//            pick(event->x(), event->y());
//        }
//        if (selectObject==-1)
//            selectObject = lastSelect;
//        if (selectObject>=0) {
//            pickTranslateAxis(event->x(), event->y());
//        }
        //if an object is selected, try to select an axis
        if (selectObject >= 0)
        {
            pickTranslateAxis(event->x(), event->y());
        }
    }
    if (selectMode == CELL_SELECT && mode == CELL_ROTATE)
    {
        if (selectObject >= 0)
        {
            pickRotateAxis(event->x(), event->y());
        }
    }
    if (selectMode==CELL_SELECT&&mode==CELL_SCALE)
    {
        if (selectObject>=0)
        {
            pickScaleAxis(event->x(), event->y());
        }
    }
    updateGL();
}

void GLWidget::myMouseMoveEvent(QMouseEvent *event)
{
    int dx = event->x() - lastPos.x();
    int dy = event->y() - lastPos.y();

    //if the left mouse button is held down
    if (event->buttons() & Qt::LeftButton) {
        if (mode==CELL_SELECT && viewMode!=CELL_FOURVIEW && selectMode==CELL_SELECT)
        {
            thisPos.setX(event->x());
            thisPos.setY(event->y());
            isAreaSelected = true;
            updateGL();
            return;
        }
        else if (mode==CELL_SELECT  &&  selectMode==CELL_EDITMESHPOINT)
        {
            thisPos.setX(event->x());
            thisPos.setY(event->y());
            isAreaSelected = true;
            if (keyValue!=CELL_SHIFT) {
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    glandular->resetSelectedPoint();
                } else if (selectObject>1) {
                    objects[selectObject-2]->resetSelectedPoint();
                }
            }
            pickPointsInArea(lastPos.x(), lastPos.y(), thisPos.x(), thisPos.y());
            updateGL();
            return;
        }
        else if (mode==CELL_SELECT  &&  selectMode==CELL_EDITMESHFACE)
        {
            thisPos.setX(event->x());
            thisPos.setY(event->y());
            isAreaSelected = true;
            if (keyValue!=CELL_SHIFT) {
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    glandular->resetSelectedFace();
                } else if (selectObject>1) {
                    objects[selectObject-2]->resetSelectedFace();
                }
            }
            pickFacesInArea(lastPos.x(), lastPos.y(), thisPos.x(), thisPos.y());
            updateGL();
            return;
        } else if (mode == CELL_CAMERAROTATE) {
            if (viewMode == CELL_PERSPECTIVE) {
                Phi += dx * 0.01;
                Theta += dy * 0.01;
                if (Phi>2*pi)
                    Phi -= 2*pi;
                if (Phi<0)
                    Phi += 2*pi;
                // dont let the point enter the north pole
                if (Theta>pi / 2 - 0.01)
                    Theta = pi / 2 - 0.01;
                if (Theta<- pi / 2 + 0.01)
                    Theta = -pi / 2 + 0.01;
            } else if (viewMode == CELL_FOURVIEW) {
                int halfWidth = windowWidth/2;
                int halfHeight = windowHeight/2;
                if (lastPos.x()>=halfWidth+CELL_FOURVIEWMARGIN && lastPos.x()<=windowWidth &&
                               lastPos.y()<=halfHeight-CELL_FOURVIEWMARGIN) {
                    Phi += dx * 0.01;
                    Theta += dy * 0.01;
                    if (Phi>2*pi)
                        Phi -= 2*pi;
                    if (Phi<0)
                        Phi += 2*pi;
                    if (Theta>pi / 2 - 0.01)
                        Theta = pi / 2 - 0.01;
                    if (Theta<- pi / 2 + 0.01)
                        Theta = -pi / 2 + 0.01;
                }
            }
        } else if (mode == CELL_CAMERAMOVE) {
            if (viewMode == CELL_PERSPECTIVE) {
                offsetX += dx*0.2;
                offsetY += dy*0.2;
            } else if (viewMode == CELL_TOP) {
                topOffsetX += dx*0.2;
                topOffsetY += dy*0.2;
            } else if (viewMode == CELL_FRONT) {
                frontOffsetX += dx*0.2;
                frontOffsetY += dy*0.2;
            } else if (viewMode == CELL_RIGHT) {
                rightOffsetX += dx*0.2;
                rightOffsetY += dy*0.2;
            } else if (viewMode == CELL_FOURVIEW) {
                int halfWidth = windowWidth/2;
                int halfHeight = windowHeight/2;
                if (lastPos.x()<=halfWidth-CELL_FOURVIEWMARGIN && lastPos.y()<=halfHeight-CELL_FOURVIEWMARGIN) {
                    //top
                    topOffsetX += dx*0.2;
                    topOffsetY += dy*0.2;
                } else if (lastPos.x()>=halfWidth+CELL_FOURVIEWMARGIN && lastPos.x()<=windowWidth &&
                           lastPos.y()<=halfHeight-CELL_FOURVIEWMARGIN) {
                    //perspective
                    offsetX += dx*0.2;
                    offsetY += dy*0.2;
                } else if (lastPos.x()<=halfWidth-CELL_FOURVIEWMARGIN &&
                           lastPos.y()>=halfHeight+CELL_FOURVIEWMARGIN && lastPos.y()<=windowHeight) {
                    //front
                    frontOffsetX += dx*0.2;
                    frontOffsetY += dy*0.2;
                } else if (lastPos.x()>=halfWidth+CELL_FOURVIEWMARGIN && lastPos.x()<=windowWidth &&
                           lastPos.y()>=halfHeight+CELL_FOURVIEWMARGIN && lastPos.y()<=windowHeight) {
                    //right
                    rightOffsetX += dx*0.2;
                    rightOffsetY += dy*0.2;
                }
            } else if (viewMode == CELL_PALNEBACED) {
                planeOffsetX += dx*0.2;
                planeOffsetY += dy*0.2;
            }
        } else if (mode == CELL_CAMERAZOOM) {
            if (viewMode == CELL_PERSPECTIVE) {
                R += dy*0.5;
            } else if (viewMode == CELL_TOP) {
                topR += dy*0.5;
            } else if (viewMode == CELL_FRONT) {
                frontR += dy*0.5;
            } else if (viewMode == CELL_RIGHT) {
                rightR += dy*0.5;
            } else if (viewMode == CELL_FOURVIEW) {
                int halfWidth = windowWidth/2;
                int halfHeight = windowHeight/2;
                if (lastPos.x()<=halfWidth-CELL_FOURVIEWMARGIN && lastPos.y()<=halfHeight-CELL_FOURVIEWMARGIN) {
                    //top
                    topR += dy*0.5;
                } else if (lastPos.x()>=halfWidth+CELL_FOURVIEWMARGIN && lastPos.x()<=windowWidth &&
                           lastPos.y()<=halfHeight-CELL_FOURVIEWMARGIN) {
                    //perspective
                    R += dy*0.5;
                } else if (lastPos.x()<=halfWidth-CELL_FOURVIEWMARGIN &&
                           lastPos.y()>=halfHeight+CELL_FOURVIEWMARGIN && lastPos.y()<=windowHeight) {
                    //front
                    frontR += dy*0.5;
                } else if (lastPos.x()>=halfWidth+CELL_FOURVIEWMARGIN && lastPos.x()<=windowWidth &&
                           lastPos.y()>=halfHeight+CELL_FOURVIEWMARGIN && lastPos.y()<=windowHeight) {
                    //right
                    rightR += dy*0.5;
                }
            } else if (viewMode == CELL_PALNEBACED) {
                planeR += dy*0.5;
            }
        } else if ((selectMode==CELL_EDITMESHPOINT||selectMode==CELL_EDITMESHFACE)&&mode==CELL_TRANSLATE) {
            Vector3 center;
            int num=0;
            if (selectMode==CELL_EDITMESHPOINT) {
                if (selectObject==0) {
                    num = glandular->selectPointsCenter(center);
                } else if (selectObject>1) {
                    num = objects[selectObject-2]->selectPointsCenter(center);
                }
            }
            else if (selectMode==CELL_EDITMESHFACE) {
                if (selectObject==0) {
                    num = glandular->selectFacesCenter(center);
                } else if (selectObject>1) {
                    num = objects[selectObject-2]->selectFacesCenter(center);
                }
            }
            if (num>0) {
                if (selectTranslateAxis == CELL_TRANSLATEAXISX || selectTranslateAxis == CELL_TRANSLATEAXISXY) {
                    GLint    viewport[4];
                    GLdouble modelview[16];
                    GLdouble projection[16];
                    GLfloat  winX, winY;
                    GLdouble posX, posY, posZ;

                    glMatrixMode(GL_PROJECTION);
                    glLoadIdentity();
                    gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                    glMatrixMode(GL_MODELVIEW);
                    glLoadIdentity();
                    gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                              0.0,0.0,0.0, 0.0,1.0,0.0);
                    glGetIntegerv(GL_VIEWPORT, viewport);
                    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                    glGetDoublev(GL_PROJECTION_MATRIX, projection);

                    winX = (float)lastPos.x() ;
                    winY = viewport[3] - (float)lastPos.y();
                    gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                    double x = 2*cos(Phi)*cos(Theta);
                    double y = 2*sin(Theta);
                    double z = 2*sin(Phi)*cos(Theta);
                    double ix, iy, iz;
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               0.0, 0.0, 1.0, center.z/R*2.0, ix, iy, iz);

                    winX = (float)event->x();
                    winY = viewport[3] - (float)event->y();
                    gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                    double nix, niy, niz;
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               0.0, 0.0, 1.0, center.z/R*2.0, nix, niy, niz);

                    if (selectObject==0 && glandular->isSurfaceConstructed()) {
                        if (selectMode==CELL_EDITMESHPOINT) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISX) {
                                if (editFeather==0.0) {
                                    glandular->moveSelectPoints(Vector3((nix-ix)/2.0*R, 0.0, 0.0));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectPointsFeather(Vector3((nix-ix)/2.0*R, 0.0, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    glandular->moveSelectPoints(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectPointsFeather(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            }
                        } else if (selectMode==CELL_EDITMESHFACE) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISX) {
                                if (editFeather==0.0) {
                                    glandular->moveSelectFaces(Vector3((nix-ix)/2.0*R, 0.0, 0.0));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectFacesFeather(Vector3((nix-ix)/2.0*R, 0.0, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    glandular->moveSelectFaces(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectFacesFeather(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            }
                        }
                    } else if (selectObject>1) {
                        if (selectMode==CELL_EDITMESHPOINT) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISX) {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectPoints(Vector3((nix-ix)/2.0*R, 0.0, 0.0));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectPointsFeather(Vector3((nix-ix)/2.0*R, 0.0, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectPoints(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectPointsFeather(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            }
                        } else if (selectMode==CELL_EDITMESHFACE) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISX) {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectFaces(Vector3((nix-ix)/2.0*R, 0.0, 0.0));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectFacesFeather(Vector3((nix-ix)/2.0*R, 0.0, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectFaces(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectFacesFeather(Vector3((nix-ix)/2.0*R, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            }
                        }
                    }
                } else if (selectTranslateAxis == CELL_TRANSLATEAXISY || selectTranslateAxis == CELL_TRANSLATEAXISYZ) {
                    GLint    viewport[4];
                    GLdouble modelview[16];
                    GLdouble projection[16];
                    GLfloat  winX, winY;
                    GLdouble posX, posY, posZ;

                    glMatrixMode(GL_PROJECTION);
                    glLoadIdentity();
                    gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                    glMatrixMode(GL_MODELVIEW);
                    glLoadIdentity();
                    gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                              0.0,0.0,0.0, 0.0,1.0,0.0);
                    glGetIntegerv(GL_VIEWPORT, viewport);
                    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                    glGetDoublev(GL_PROJECTION_MATRIX, projection);

                    winX = (float)lastPos.x() ;
                    winY = viewport[3] - (float)lastPos.y();
                    gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                    double x = 2*cos(Phi)*cos(Theta);
                    double y = 2*sin(Theta);
                    double z = 2*sin(Phi)*cos(Theta);
                    double ix, iy, iz;
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                              1.0, 0.0, 0.0, center.x/R*2.0, ix, iy, iz);

                    winX = (float)event->x();
                    winY = viewport[3] - (float)event->y();
                    gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                    double nix, niy, niz;
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               1.0, 0.0, 0.0, center.x/R*2.0, nix, niy, niz);

                    if (selectObject==0 && glandular->isSurfaceConstructed()) {
                        if (selectMode==CELL_EDITMESHPOINT) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISY) {
                                if (editFeather==0.0) {
                                    glandular->moveSelectPoints(Vector3(0.0, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectPointsFeather(Vector3(0.0, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    glandular->moveSelectPoints(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectPointsFeather(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        } else if (selectMode==CELL_EDITMESHFACE) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISY) {
                                if (editFeather==0.0) {
                                    glandular->moveSelectFaces(Vector3(0.0, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectFacesFeather(Vector3(0.0, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    glandular->moveSelectFaces(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectFacesFeather(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        }
                    } else if (selectObject>1) {
                        if (selectMode==CELL_EDITMESHPOINT) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISY) {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectPoints(Vector3(0.0, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectPointsFeather(Vector3(0.0, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectPoints(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectPointsFeather(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        } else if (selectMode==CELL_EDITMESHFACE) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISY) {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectFaces(Vector3(0.0, (niy-iy)/2.0*R, 0.0));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectFacesFeather(Vector3(0.0, (niy-iy)/2.0*R, 0.0), editFeather);
                                }
                            } else {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectFaces(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectFacesFeather(Vector3(0.0, (niy-iy)/2.0*R, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        }
                    }
                } else if (selectTranslateAxis == CELL_TRANSLATEAXISZ || selectTranslateAxis == CELL_TRANSLATEAXISZX) {
                    GLint    viewport[4];
                    GLdouble modelview[16];
                    GLdouble projection[16];
                    GLfloat  winX, winY;
                    GLdouble posX, posY, posZ;

                    glMatrixMode(GL_PROJECTION);
                    glLoadIdentity();
                    gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                    glMatrixMode(GL_MODELVIEW);
                    glLoadIdentity();
                    gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                              0.0,0.0,0.0, 0.0,1.0,0.0);
                    glGetIntegerv(GL_VIEWPORT, viewport);
                    glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                    glGetDoublev(GL_PROJECTION_MATRIX, projection);

                    winX = (float)lastPos.x() ;
                    winY = viewport[3] - (float)lastPos.y();
                    gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                    double x = 2*cos(Phi)*cos(Theta);
                    double y = 2*sin(Theta);
                    double z = 2*sin(Phi)*cos(Theta);
                    double ix, iy, iz;
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               0.0, 1.0, 0.0, center.y/R*2.0, ix, iy, iz);

                    winX = (float)event->x();
                    winY = viewport[3] - (float)event->y();
                    gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                    double nix, niy, niz;
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               0.0, 1.0, 0.0, center.y/R*2.0, nix, niy, niz);

                    if (selectObject==0 && glandular->isSurfaceConstructed()) {
                        if (selectMode==CELL_EDITMESHPOINT) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISZ) {
                                if (editFeather==0.0) {
                                    glandular->moveSelectPoints(Vector3(0.0, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectPointsFeather(Vector3(0.0, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                            else {
                                if (editFeather==0.0) {
                                    glandular->moveSelectPoints(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectPointsFeather(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        } else if (selectMode==CELL_EDITMESHFACE) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISZ) {
                                if (editFeather==0.0) {
                                    glandular->moveSelectFaces(Vector3(0.0, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectFacesFeather(Vector3(0.0, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                            else {
                                if (editFeather==0.0) {
                                    glandular->moveSelectFaces(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    glandular->moveSelectFacesFeather(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        }
                    } else if (selectObject>1) {
                        if (selectMode==CELL_EDITMESHPOINT) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISZ) {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectPoints(Vector3(0.0, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectPointsFeather(Vector3(0.0, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                            else {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectPoints(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectPointsFeather(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        } else if (selectMode==CELL_EDITMESHFACE) {
                            if (selectTranslateAxis == CELL_TRANSLATEAXISZ) {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectFaces(Vector3(0.0, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectFacesFeather(Vector3(0.0, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                            else {
                                if (editFeather==0.0) {
                                    objects[selectObject-2]->moveSelectFaces(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R));
                                } else if (editFeather>0.0) {
                                    objects[selectObject-2]->moveSelectFacesFeather(Vector3((nix-ix)/2.0*R, 0.0, (niz-iz)/2.0*R), editFeather);
                                }
                            }
                        }
                    }
                }
            }
        } else if (selectMode==CELL_SELECT && mode == CELL_TRANSLATE) {
            if (selectTranslateAxis == CELL_TRANSLATEAXISX || selectTranslateAxis == CELL_TRANSLATEAXISXY) {

                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY; // xy window coordinates
                GLdouble posX, posY, posZ; // xyz 3D space coordinates

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisZ(0), glandular->getAxisZ(1), glandular->getAxisZ(2),
                                           -glandular->getTranslateZ()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisZ(0), objects[selectObject-2]->getAxisZ(1), objects[selectObject-2]->getAxisZ(2),
                                           -objects[selectObject-2]->getTranslateZ()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisZ(0), glandular->getAxisZ(1), glandular->getAxisZ(2),
                                           -glandular->getTranslateZ()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisZ(0), objects[selectObject-2]->getAxisZ(1), objects[selectObject-2]->getAxisZ(2),
                                           -objects[selectObject-2]->getTranslateZ()/R*2.0, nix, niy, niz);

                //create the necessary vectors to compute transformation
                double v1[4] = {ix, iy, iz, 1.0}; //point of the first click
                double v2[4] = {nix, niy, niz, 1.0}; //point of the current position
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                if(selectObject==0 || selectObject > 1) {
                    addTranslateX((v4[0]-v3[0])/2.0*R);
                }

            } else if (selectTranslateAxis == CELL_TRANSLATEAXISY || selectTranslateAxis == CELL_TRANSLATEAXISYZ) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisX(0), glandular->getAxisX(1), glandular->getAxisX(2),
                                           -glandular->getTranslateX()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisX(0), objects[selectObject-2]->getAxisX(1), objects[selectObject-2]->getAxisX(2),
                                           -objects[selectObject-2]->getTranslateX()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisX(0), glandular->getAxisX(1), glandular->getAxisX(2),
                                           -glandular->getTranslateX()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisX(0), objects[selectObject-2]->getAxisX(1), objects[selectObject-2]->getAxisX(2),
                                           -objects[selectObject-2]->getTranslateX()/R*2.0, nix, niy, niz);

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                if(selectObject==0 || selectObject > 1)
                    addTranslateY((v4[1]-v3[1])/2.0*R);

            } else if (selectTranslateAxis == CELL_TRANSLATEAXISZ || selectTranslateAxis == CELL_TRANSLATEAXISZX) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisY(0), glandular->getAxisY(1), glandular->getAxisY(2),
                                           -glandular->getTranslateY()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisY(0), objects[selectObject-2]->getAxisY(1), objects[selectObject-2]->getAxisY(2),
                                           -objects[selectObject-2]->getTranslateY()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisY(0), glandular->getAxisY(1), glandular->getAxisY(2),
                                           -glandular->getTranslateY()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisY(0), objects[selectObject-2]->getAxisY(1), objects[selectObject-2]->getAxisY(2),
                                           -objects[selectObject-2]->getTranslateY()/R*2.0, nix, niy, niz);

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                if(selectObject==0 || selectObject > 1)
                    addTranslateZ((v4[2]-v3[2])/2.0*R);

            }
            else if (selectTranslateAxis == CELL_CTRLPOINT1)
            {
                //The selected object moves along a plane parallel with the screen
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x();
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;

                Vector3 planeNormal(posX, posY, posZ);
                planeNormal.Normalize();
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    double d = -(glandular->getTranslateX()/R*2.0*planeNormal.x +
                                 glandular->getTranslateY()/R*2.0*planeNormal.y +
                                 glandular->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, ix, iy, iz);
                }
                else if (selectObject>1) {
                    double d = -(objects[selectObject-2]->getTranslateX()/R*2.0*planeNormal.x +
                            objects[selectObject-2]->getTranslateY()/R*2.0*planeNormal.y +
                            objects[selectObject-2]->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, ix, iy, iz);
                }

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;

                if (selectObject==0) {
                    double d = -(glandular->getTranslateX()/R*2.0*planeNormal.x+glandular->getTranslateY()/R*2.0*planeNormal.y+glandular->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, nix, niy, niz);
                }
                else if (selectObject>1) {
                    double d = -(objects[selectObject-2]->getTranslateX()/R*2.0*planeNormal.x+
                            objects[selectObject-2]->getTranslateY()/R*2.0*planeNormal.y+
                            objects[selectObject-2]->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, nix, niy, niz);
                }

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};

                if (selectObject==0 || selectObject > 1) {
                    addTranslateCtrlPt1X((v2[0]-v1[0])/2.0*R);
                    addTranslateCtrlPt1Y((v2[1]-v1[1])/2.0*R);
                    addTranslateCtrlPt1Z((v2[2]-v1[2])/2.0*R);
                }
            }
            else if (selectTranslateAxis == CELL_CTRLPOINT2)
            {

                //The selected object moves along a plane parallel with the screen
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x();
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;

                Vector3 planeNormal(posX, posY, posZ);
                planeNormal.Normalize();
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    double d = -(glandular->getTranslateX()/R*2.0*planeNormal.x +
                                 glandular->getTranslateY()/R*2.0*planeNormal.y +
                                 glandular->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, ix, iy, iz);
                }
                else if (selectObject>1) {
                    double d = -(objects[selectObject-2]->getTranslateX()/R*2.0*planeNormal.x +
                            objects[selectObject-2]->getTranslateY()/R*2.0*planeNormal.y +
                            objects[selectObject-2]->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, ix, iy, iz);
                }

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;

                if (selectObject==0) {
                    double d = -(glandular->getTranslateX()/R*2.0*planeNormal.x+glandular->getTranslateY()/R*2.0*planeNormal.y+glandular->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, nix, niy, niz);
                }
                else if (selectObject>1) {
                    double d = -(objects[selectObject-2]->getTranslateX()/R*2.0*planeNormal.x+
                            objects[selectObject-2]->getTranslateY()/R*2.0*planeNormal.y+
                            objects[selectObject-2]->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, nix, niy, niz);
                }

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};

                if (selectObject==0 || selectObject > 1) {
                    addTranslateCtrlPt2X((v2[0]-v1[0])/2.0*R);
                    addTranslateCtrlPt2Y((v2[1]-v1[1])/2.0*R);
                    addTranslateCtrlPt2Z((v2[2]-v1[2])/2.0*R);
                }
            }
            else if(selectTranslateAxis == CELL_TRANSLATEDEPTH) {

                //The selected object moves along a vector that goes into/out of the screen
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;
                GLdouble posX2, posY2, posZ2;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastClickPos.x();
                winY = viewport[3] - (float)lastClickPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                gluUnProject(winX, winY, 0.0, modelview, projection, viewport, &posX2, &posY2, &posZ2);
                Vector3 planeNormal(posX2-posX, posY2-posY, posZ2-posZ);
                planeNormal.Normalize();
                if (selectObject==0 || selectObject > 1)
                {
                    if(-lastPos.y()+event->y() > 0)
                    {
                        if (objects[selectObject-2]->getType()==CELL_LINE)
                        {
                            addTranslateCtrlPt1X(planeNormal.x);
                            addTranslateCtrlPt1Y(planeNormal.y);
                            addTranslateCtrlPt1Z(planeNormal.z);

                            addTranslateCtrlPt2X(planeNormal.x);
                            addTranslateCtrlPt2Y(planeNormal.y);
                            addTranslateCtrlPt2Z(planeNormal.z);
                        }
                        else
                        {
                            addTranslateX(planeNormal.x);
                            addTranslateY(planeNormal.y);
                            addTranslateZ(planeNormal.z);
                        }
                    }
                    else
                    {
                        if (objects[selectObject-2]->getType()==CELL_LINE)
                        {
                            addTranslateCtrlPt1X(-(planeNormal.x));
                            addTranslateCtrlPt1Y(-(planeNormal.y));
                            addTranslateCtrlPt1Z(-(planeNormal.z));

                            addTranslateCtrlPt2X(-(planeNormal.x));
                            addTranslateCtrlPt2Y(-(planeNormal.y));
                            addTranslateCtrlPt2Z(-(planeNormal.z));
                        }
                        else
                        {
                            addTranslateX(-(planeNormal.x));
                            addTranslateY(-(planeNormal.y));
                            addTranslateZ(-(planeNormal.z));
                        }
                    }
                }
            }
        } else if (selectMode==CELL_SELECT&&mode==CELL_ROTATE) {
            if (selectRotateAxis == CELL_ROTATEAXISX) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;

                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               glandular->getAxisX(0), glandular->getAxisX(1), glandular->getAxisX(2),
                                               -glandular->getTranslateX()/R*2.0, ix, iy, iz);
                }
                else if (selectObject>1) {
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               objects[selectObject-2]->getAxisX(0), objects[selectObject-2]->getAxisX(1), objects[selectObject-2]->getAxisX(2),
                                               -objects[selectObject-2]->getTranslateX()/R*2.0, ix, iy, iz);
                }

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               glandular->getAxisX(0), glandular->getAxisX(1), glandular->getAxisX(2),
                                               -glandular->getTranslateX()/R*2.0, nix, niy, niz);
                }
                else if (selectObject>1) {
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               objects[selectObject-2]->getAxisX(0), objects[selectObject-2]->getAxisX(1), objects[selectObject-2]->getAxisX(2),
                                               -objects[selectObject-2]->getTranslateX()/R*2.0, nix, niy, niz);
                }

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                double theta = CellMath::crossAngle(v4[2], v4[1], v3[2], v3[1]);
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    addRotateX(theta);
                    glandular->AxisRotate();
                } else if (selectObject>1) {
                    addRotateX(theta);
                    (objects[selectObject-2])->AxisRotate();
                }

            } else if (selectRotateAxis == CELL_ROTATEAXISY) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               glandular->getAxisY(0), glandular->getAxisY(1), glandular->getAxisY(2),
                                               -glandular->getTranslateY()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               objects[selectObject-2]->getAxisY(0), objects[selectObject-2]->getAxisY(1), objects[selectObject-2]->getAxisY(2),
                                               -objects[selectObject-2]->getTranslateY()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               glandular->getAxisY(0), glandular->getAxisY(1), glandular->getAxisY(2),
                                               -glandular->getTranslateY()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               objects[selectObject-2]->getAxisY(0), objects[selectObject-2]->getAxisY(1), objects[selectObject-2]->getAxisY(2),
                                               -objects[selectObject-2]->getTranslateY()/R*2.0, nix, niy, niz);

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                double theta = CellMath::crossAngle(v4[0], v4[2], v3[0], v3[2]);
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    addRotateY(theta);
                    glandular->AxisRotate();
                } else if (selectObject>1) {
                    addRotateY(theta);
                    (objects[selectObject-2])->AxisRotate();
                }

            } else if (selectRotateAxis == CELL_ROTATEAXISZ) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;

                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               glandular->getAxisZ(0), glandular->getAxisZ(1), glandular->getAxisZ(2),
                                               -glandular->getTranslateZ()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               objects[selectObject-2]->getAxisZ(0), objects[selectObject-2]->getAxisZ(1), objects[selectObject-2]->getAxisZ(2),
                                               -objects[selectObject-2]->getTranslateZ()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               glandular->getAxisZ(0), glandular->getAxisZ(1), glandular->getAxisZ(2),
                                               -glandular->getTranslateZ()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                               objects[selectObject-2]->getAxisZ(0), objects[selectObject-2]->getAxisZ(1), objects[selectObject-2]->getAxisZ(2),
                                               -objects[selectObject-2]->getTranslateZ()/R*2.0, nix, niy, niz);

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                double theta = CellMath::crossAngle(v4[1], v4[0], v3[1], v3[0]);
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    addRotateZ(theta);
                    glandular->AxisRotate();
                } else if (selectObject>1) {
                    addRotateZ(theta);
                    (objects[selectObject-2])->AxisRotate();
                }

            } /*else if (selectRotateAxis == CELL_CTRLPOINT2) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x();
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;

                Vector3 planeNormal(posX, posY, posZ); //axis of the ray tracer for mouse click
                planeNormal.Normalize();
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    double d = -(glandular->getTranslateX()/R*2.0*planeNormal.x +
                                 glandular->getTranslateY()/R*2.0*planeNormal.y +
                                 glandular->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, ix, iy, iz);
                }
                else if (selectObject>1) {
                    double d = -(objects[selectObject-2]->getTranslateX()/R*2.0*planeNormal.x +
                            objects[selectObject-2]->getTranslateY()/R*2.0*planeNormal.y +
                            objects[selectObject-2]->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, ix, iy, iz);
                }

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;

                if (selectObject==0) {
                    double d = -(glandular->getTranslateX()/R*2.0*planeNormal.x+glandular->getTranslateY()/R*2.0*planeNormal.y+glandular->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, nix, niy, niz);
                }
                else if (selectObject>1) {
                    double d = -(objects[selectObject-2]->getTranslateX()/R*2.0*planeNormal.x+
                            objects[selectObject-2]->getTranslateY()/R*2.0*planeNormal.y+
                            objects[selectObject-2]->getTranslateZ()/R*2.0*planeNormal.z);
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           planeNormal.x, planeNormal.y, planeNormal.z, d, nix, niy, niz);
                }

                double v1[4] = {ix, iy, iz, 1.0};       //initial mouse point
                double v2[4] = {nix, niy, niz, 1.0};    //ending mouse point
                double v3[4], v4[4];

                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                double theta = CellMath::crossAngle(v4[2], v4[1], v3[2], v3[1]);
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
//                    addRotateX(theta);
//                    glandular->AxisRotate();
                    glandular->addRotateCtrl(theta, planeNormal.x, planeNormal.y, planeNormal.z);
                } else if (selectObject>1) {
//                    addRotateX(theta);
//                    (objects[selectObject-2])->AxisRotate();
                    (objects[selectObject-2])->addRotateCtrl(theta, planeNormal.x, planeNormal.y, planeNormal.z);
                }
            }*/

        } else if (selectMode==CELL_SELECT&&mode==CELL_SCALE) {
            if (selectScaleAxis == CELL_SCALEAXISX) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisZ(0), glandular->getAxisZ(1), glandular->getAxisZ(2),
                                           -glandular->getTranslateZ()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisZ(0), objects[selectObject-2]->getAxisZ(1), objects[selectObject-2]->getAxisZ(2),
                                           -objects[selectObject-2]->getTranslateZ()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisZ(0), glandular->getAxisZ(1), glandular->getAxisZ(2),
                                           -glandular->getTranslateZ()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisZ(0), objects[selectObject-2]->getAxisZ(1), objects[selectObject-2]->getAxisZ(2),
                                           -objects[selectObject-2]->getTranslateZ()/R*2.0, nix, niy, niz);

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                if (selectObject==0 && glandular->isSurfaceConstructed())
                    setScaleX(glandular->getScaleX()*((v4[0]-v3[0])+0.2)/0.2);
                else if (selectObject>1)
                    setScaleX((objects[selectObject-2])->getScaleX()*((v4[0]-v3[0])+0.2)/0.2);
            } else if (selectScaleAxis == CELL_SCALEAXISY) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisX(0), glandular->getAxisX(1), glandular->getAxisX(2),
                                           -glandular->getTranslateX()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisX(0), objects[selectObject-2]->getAxisX(1), objects[selectObject-2]->getAxisX(2),
                                           -objects[selectObject-2]->getTranslateX()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisX(0), glandular->getAxisX(1), glandular->getAxisX(2),
                                           -glandular->getTranslateX()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisX(0), objects[selectObject-2]->getAxisX(1), objects[selectObject-2]->getAxisX(2),
                                           -objects[selectObject-2]->getTranslateX()/R*2.0, nix, niy, niz);


                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                if (selectObject==0 && glandular->isSurfaceConstructed())
                    setScaleY(glandular->getScaleY()*((v4[1]-v3[1])+0.2)/0.2);
                else if (selectObject>1)
                    setScaleY((objects[selectObject-2])->getScaleY()*((v4[1]-v3[1])+0.2)/0.2);
            } else if (selectScaleAxis == CELL_SCALEAXISZ) {
                GLint    viewport[4];
                GLdouble modelview[16];
                GLdouble projection[16];
                GLfloat  winX, winY;
                GLdouble posX, posY, posZ;

                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                gluPerspective(45,(double)windowWidth/(double)windowHeight,0.01,1000);
                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();
                gluLookAt(2*cos(Phi)*cos(Theta), 2*sin(Theta), 2*sin(Phi)*cos(Theta),
                          0.0,0.0,0.0, 0.0,1.0,0.0);
                glGetIntegerv(GL_VIEWPORT, viewport);
                glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
                glGetDoublev(GL_PROJECTION_MATRIX, projection);

                winX = (float)lastPos.x() ;
                winY = viewport[3] - (float)lastPos.y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double x = 2*cos(Phi)*cos(Theta);
                double y = 2*sin(Theta);
                double z = 2*sin(Phi)*cos(Theta);
                double ix=0.0;
                double iy=0.0;
                double iz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisY(0), glandular->getAxisY(1), glandular->getAxisY(2),
                                           -glandular->getTranslateY()/R*2.0, ix, iy, iz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisY(0), objects[selectObject-2]->getAxisY(1), objects[selectObject-2]->getAxisY(2),
                                           -objects[selectObject-2]->getTranslateY()/R*2.0, ix, iy, iz);

                winX = (float)event->x();
                winY = viewport[3] - (float)event->y();
                gluUnProject(winX, winY, 0.9, modelview, projection, viewport, &posX, &posY, &posZ);
                double nix=0.0;
                double niy=0.0;
                double niz=0.0;
                if (selectObject==0 && glandular->isSurfaceConstructed())
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           glandular->getAxisY(0), glandular->getAxisY(1), glandular->getAxisY(2),
                                           -glandular->getTranslateY()/R*2.0, nix, niy, niz);
                else if (selectObject>1)
                    CellMath::lineIntersection(posX-x, x, posY-y, y, posZ-z, z,
                                           objects[selectObject-2]->getAxisY(0), objects[selectObject-2]->getAxisY(1), objects[selectObject-2]->getAxisY(2),
                                           -objects[selectObject-2]->getTranslateY()/R*2.0, nix, niy, niz);

                double v1[4] = {ix, iy, iz, 1.0};
                double v2[4] = {nix, niy, niz, 1.0};
                double v3[4], v4[4];
                if (selectObject==0 && glandular->isSurfaceConstructed()) {
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(glandular->rotateMatrix, v2, v4);
                } else if (selectObject>1) {
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v1, v3);
                    CellMath::matMutiplyVector(objects[selectObject-2]->rotateMatrix, v2, v4);
                }

                if (selectObject==0)
                    setScaleZ(glandular->getScaleZ()*((v4[2]-v3[2])+0.2)/0.2);
                else if (selectObject>1)
                    setScaleZ((objects[selectObject-2])->getScaleZ()*((v4[2]-v3[2])+0.2)/0.2);
            } else if (selectScaleAxis == CELL_SCALEAXISXYZ) {
                if (selectObject==0) {
                    setScaleX(glandular->getScaleX()*(dx+200.0)/200.0);
                    setScaleY(glandular->getScaleY()*(dx+200.0)/200.0);
                    setScaleZ(glandular->getScaleZ()*(dx+200.0)/200.0);
                } else if (selectObject>1) {
                    setScaleX((objects[selectObject-2])->getScaleX()*(dx+200.0)/200.0);
                    setScaleY((objects[selectObject-2])->getScaleY()*(dx+200.0)/200.0);
                    setScaleZ((objects[selectObject-2])->getScaleZ()*(dx+200.0)/200.0);
                }
            }
        }
    }
    lastPos = event->pos();
    updateGL();
}

void GLWidget::myMouseReleaseEvent(QMouseEvent *event)
{
    //COMBINE
    if (mode==CELL_SELECT || mode == CELL_TRANSLATE || mode == CELL_EDITMESHPOINT || mode == CELL_EDITMESHFACE)
    {
        isAreaSelected = false;
    }
    updateGL();
}

void GLWidget::wheelEvent(QWheelEvent *event)
{
    int numDegrees = event->delta() / 8;
    double numSteps = (double)numDegrees / 15;
    if (event->orientation() == Qt::Vertical) {
        if (viewMode == CELL_PERSPECTIVE) {
            R -= numSteps;
        } else if (viewMode == CELL_TOP) {
            topR -= numSteps;
        } else if (viewMode == CELL_FRONT) {
            frontR -= numSteps;
        } else if (viewMode == CELL_RIGHT) {
            rightR -= numSteps;
        } else if (viewMode == CELL_FOURVIEW) {
            int halfWidth = windowWidth/2;
            int halfHeight = windowHeight/2;
            if (event->x()<=halfWidth-CELL_FOURVIEWMARGIN && event->y()<=halfHeight-CELL_FOURVIEWMARGIN) {
                //top
                topR -= numSteps;
            } else if (event->x()>=halfWidth+CELL_FOURVIEWMARGIN && event->x()<=windowWidth &&
                       event->y()<=halfHeight-CELL_FOURVIEWMARGIN) {
                //perspective
                R -= numSteps;
            } else if (event->x()<=halfWidth-CELL_FOURVIEWMARGIN &&
                       event->y()>=halfHeight+CELL_FOURVIEWMARGIN && event->y()<=windowHeight) {
                //front
                frontR -= numSteps;
            } else if (event->x()>=halfWidth+CELL_FOURVIEWMARGIN && event->x()<=windowWidth &&
                       event->y()>=halfHeight+CELL_FOURVIEWMARGIN && event->y()<=windowHeight) {
                //right
                rightR -= numSteps;
            }
        } else if (viewMode == CELL_PALNEBACED) {
            planeR -= numSteps;
        }
    }
    updateGL();
}
